package com.cardone.platform.authority.service;

import java.util.List;

import lombok.Getter;
import lombok.Setter;

import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;

import com.cardone.common.dto.PaginationDto;
import com.cardone.context.ContextHolder;
import com.cardone.context.Contexts;
import com.cardone.context.DictionaryException;
import com.cardone.platform.authority.dao.NavigationDao;
import com.cardone.platform.authority.dto.NavigationDto;
import com.cardone.platform.configuration.service.DictionaryService;
import com.cardone.platform.configuration.service.SiteService;

/**
 * 导航服务
 *
 * @author yaohaitao
 *
 */
@Getter
@Setter
public class NavigationDefaultService implements NavigationService {
	@Override
	public int deleteByIds(final NavigationDto deleteNavigation) {
		return ContextHolder.getBean(NavigationDao.class).deleteByIds(deleteNavigation);
	}

	@Override
	public <P> P findByCodeOrId(final Class<P> mappedClass, final NavigationDto findNavigation) {
		return ContextHolder.getBean(NavigationDao.class).findByCodeOrId(mappedClass, findNavigation);
	}

	@Override
	public <P> P findById(final Class<P> mappedClass, final NavigationDto findNavigation) {
		return ContextHolder.getBean(NavigationDao.class).findById(mappedClass, findNavigation);
	}

	@Override
	public <P> List<P> findList(final Class<P> mappedClass) {
		return ContextHolder.getBean(NavigationDao.class).findList(mappedClass);
	}

	@Override
	public <P> List<P> findListByLikeCode(final Class<P> mappedClass, final NavigationDto findListNavigation) {
		return ContextHolder.getBean(NavigationDao.class).findListByLikeCode(mappedClass, findListNavigation);
	}

	@Override
	public List<NavigationDto> findListByParentCode(final String siteCode, final String typeCode, final String parentCode) {
		return ContextHolder.getBean(NavigationDao.class).findListByParentCode(NavigationDto.class, siteCode, typeCode, parentCode);
	}

	@Override
	public List<NavigationDto> findListByParentCodeForTree(final String siteCode, final String typeCode, final String parentCode, final int level) {
		final String newTypeCode = StringUtils.defaultString(typeCode, Contexts.main.name());

		final List<NavigationDto> navigationList = ContextHolder.getBean(NavigationService.class).findListByParentCode(siteCode, newTypeCode, parentCode);

		if (CollectionUtils.isEmpty(navigationList)) {
			return navigationList;
		}

		if (level < 1) {
			return navigationList;
		}

		for (final NavigationDto navigationDto : navigationList) {
			if (navigationDto.getChildTotal() < 1) {
				continue;
			}

			navigationDto.setChilds(ContextHolder.getBean(NavigationService.class).findListByParentIdForTree(siteCode, newTypeCode, navigationDto.getId(), (level - 1)));
		}

		return navigationList;
	}

	@Override
	public List<NavigationDto> findListByParentId(final String siteCode, final String typeCode, final String parentId) {
		return ContextHolder.getBean(NavigationDao.class).findListByParentId(NavigationDto.class, siteCode, typeCode, parentId);
	}

	@Override
	public List<NavigationDto> findListByParentIdForTree(final String siteCode, final String typeCode, final String parentId, final int level) {
		final String newTypeCode = StringUtils.defaultString(typeCode, Contexts.main.name());

		final List<NavigationDto> navigationList = ContextHolder.getBean(NavigationService.class).findListByParentId(siteCode, newTypeCode, parentId);

		if (CollectionUtils.isEmpty(navigationList)) {
			return navigationList;
		}

		if (level < 1) {
			return navigationList;
		}

		for (final NavigationDto navigationDto : navigationList) {
			if (navigationDto.getChildTotal() < 1) {
				continue;
			}

			navigationDto.setChilds(ContextHolder.getBean(NavigationService.class).findListByParentIdForTree(siteCode, newTypeCode, navigationDto.getId(), (level - 1)));
		}

		return navigationList;
	}

	@Override
	public void init(final List<NavigationDto> initNavigationList) {
		if (CollectionUtils.isEmpty(initNavigationList)) {
			return;
		}

		for (final NavigationDto initNavigation : initNavigationList) {
			if (StringUtils.isBlank(initNavigation.getSiteId())) {
				final String siteId = ContextHolder.getBean(SiteService.class).readIdByCode(initNavigation.getSiteCode());

				if (StringUtils.isBlank(siteId)) {
					continue;
				}

				initNavigation.setSiteId(siteId);
			}

			if (StringUtils.isBlank(initNavigation.getTypeId())) {
				final String typeId = ContextHolder.getBean(DictionaryService.class).readIdByTypeCodeAndCode(initNavigation.getTypeTypeCode(), initNavigation.getTypeCode());

				if (StringUtils.isBlank(typeId)) {
					continue;
				}

				initNavigation.setTypeId(typeId);
			}

			final NavigationDto oldNavigation = ContextHolder.getBean(NavigationDao.class).saveByIdOrCode(NavigationDto.class, initNavigation);

			if (CollectionUtils.isEmpty(initNavigation.getChilds())) {
				continue;
			}

			for (final NavigationDto childNavigation : initNavigation.getChilds()) {
				childNavigation.setSiteId(oldNavigation.getSiteId());

				childNavigation.setTypeId(oldNavigation.getTypeId());

				childNavigation.setParentId(oldNavigation.getId());

				childNavigation.setTreeTypeCode(initNavigation.getTreeTypeCode());

				childNavigation.setTreeCode(initNavigation.getTreeCode());
			}

			this.init(initNavigation.getChilds());
		}
	}

	@Override
	public int insertByCode(final NavigationDto insertNavigation) {
		if (StringUtils.isBlank(insertNavigation.getSiteId())) {
			throw new DictionaryException("站点标识不能为空值").setTypeCode("navigation").setCode("isBlankSiteId");
		}

		if (StringUtils.isBlank(insertNavigation.getTypeId())) {
			throw new DictionaryException("类别标识不能为空值").setTypeCode("navigation").setCode("isBlankTypeId");
		}

		if (StringUtils.isBlank(insertNavigation.getCode())) {
			throw new DictionaryException("编号不能为空值").setTypeCode("navigation").setCode("isBlankCode");
		}

		if (StringUtils.isBlank(insertNavigation.getName())) {
			throw new DictionaryException("名称不能为空值").setTypeCode("navigation").setCode("isBlankName");
		}

		final int oldCount = this.readByCodeNqIdForCount(insertNavigation);

		if (oldCount > 0) {
			throw new DictionaryException("编号有冲突").setTypeCode("navigation").setCode("oldData");
		}

		return ContextHolder.getBean(NavigationDao.class).insertByCode(insertNavigation);
	}

	@Override
	public <P> PaginationDto<P> paginationByLikeCode(final Class<P> mappedClass, final NavigationDto paginationNavigation) {
		return ContextHolder.getBean(NavigationDao.class).paginationByLikeCode(mappedClass, paginationNavigation);
	}

	@Override
	public Integer readByCodeNqIdForCount(final NavigationDto readNavigation) {
		return ContextHolder.getBean(NavigationDao.class).readByCodeNqIdForCount(readNavigation);
	}

	@Override
	public <P> P saveByIdOrCode(final Class<P> mappedClass, final NavigationDto saveNavigation) {
		if (StringUtils.isBlank(saveNavigation.getSiteId())) {
			throw new DictionaryException("站点标识不能为空值").setTypeCode("navigation").setCode("isBlankSiteId");
		}

		if (StringUtils.isBlank(saveNavigation.getTypeId())) {
			throw new DictionaryException("类别标识不能为空值").setTypeCode("navigation").setCode("isBlankTypeId");
		}

		if (StringUtils.isBlank(saveNavigation.getCode())) {
			throw new DictionaryException("编号不能为空值").setTypeCode("navigation").setCode("isBlankCode");
		}

		if (StringUtils.isBlank(saveNavigation.getName())) {
			throw new DictionaryException("名称不能为空值").setTypeCode("navigation").setCode("isBlankName");
		}

		final int oldCount = this.readByCodeNqIdForCount(saveNavigation);

		if (oldCount > 0) {
			throw new DictionaryException("编号有冲突").setTypeCode("navigation").setCode("oldData");
		}

		return ContextHolder.getBean(NavigationDao.class).saveByIdOrCode(mappedClass, saveNavigation);
	}

	@Override
	public int updateByCode(final NavigationDto updateNavigation) {
		return ContextHolder.getBean(NavigationDao.class).updateByCode(updateNavigation);
	}
}